#include "formgetreceipt.h"
#include "ui_formgetreceipt.h"
#include <QDebug>
#include <QFileDialog>
#include <QDate>

FormGetReceipt::FormGetReceipt(DlgSettings *p_settings,  QWidget *parent) :
    QWidget(parent),
    mp_settings(p_settings),
    ui(new Ui::FormGetReceipt)
{
    ui->setupUi(this);
    ui->chb_show_excel->setChecked(false);
    show_excel(false);
    connect(ui->btn_form_receipt, SIGNAL(clicked()), this, SLOT(form_reciept()));
    connect(ui->chb_show_excel, SIGNAL(clicked(bool)), this, SLOT(show_excel(bool)));
    QDate now_date = QDate::currentDate();
    ui->combo_year->setCurrentIndex(now_date.year() - 2000);
    ui->combo_month->setCurrentIndex(now_date.month()-1);
    m_act_names<<"$FIO"<<"$ADDR"<<"$M-Y"<<"$TAR"<<"$SPC"<<"$TOTAL"<<"$BILL_ID";
    ui->frame_in_action->hide();
    connect(ui->combo_year, SIGNAL(currentIndexChanged(int)), this, SLOT(update_model()));
    connect(ui->combo_month, SIGNAL(currentIndexChanged(int)), this, SLOT(update_model()));
    connect(ui->combo_year, SIGNAL(currentIndexChanged(int)), this, SLOT(target_date_changed()));
    connect(ui->combo_month, SIGNAL(currentIndexChanged(int)), this, SLOT(target_date_changed()));
    connect(ui->btn_gen_bills, SIGNAL(clicked()), this, SLOT(generate_bills()));
    connect(ui->chb_do_by_lease, SIGNAL(clicked()),this,SLOT(update_model()));
    connect(ui->chb_do_by_nlease, SIGNAL(clicked()),this,SLOT(update_model()));
    connect(ui->btn_rem_bill, SIGNAL(clicked()), this, SLOT(del_selected_bill()));
    target_date_changed();
}

FormGetReceipt::~FormGetReceipt()
{
    delete ui;
}


#ifdef Q_OS_WIN
void FormGetReceipt::scan_template(SleeExcelSheet *p_sheet)
{
    if(m_act_lst.size()) return;

    int row = 0, col = 0;
    QString qstr_value;
    lakhMsg()<<RUSTR("Сканирование шаблона.");
    int cells_max = 59*39;
    int cntr = 1;
    ui->progress_bar->setMinimum(0);
    ui->progress_bar->setMaximum(cells_max);
    ui->progress_bar->setValue(0);
    for(row = 1; row < 60; row ++)
        for(col =1; col < 40; col ++)
        {
            qstr_value = p_sheet->get(row, col).toString();
            lakhMsgF()<<RUSTR("Шаблон: ")<<cntr++<<"/"<<cells_max;
            ui->progress_bar->setValue(cntr);
            if(qstr_value.isEmpty()) continue;
            qDebug()<<row<<col<<qstr_value;
            if(qstr_value.at(0) == '$')
            {
                int act_index = m_act_names.indexOf(qstr_value);
                if(act_index < 0)
                {
                    lakhMsg()<<RUSTR("Внимание! Неизвестный маркер в шаблоне:")<<qstr_value;
                    continue;
                }
                QPair<int, int> qp_act_pos(row, col);
                QPair< QPair<int, int>, int > qp_act_action(qp_act_pos, act_index);
                m_act_lst.append(qp_act_action);
            }
        }
    lakhMsg()<<RUSTR("Шаблон загружен.");
    qDebug()<<"actions found: "<<m_act_lst.size();
}

QVariant FormGetReceipt::process_act(int act,  const QVariant &qv_bill_index)
{
    SLEE_HDB_REC qh_bill_data = mp_dbms->get_data(LAKDB_BILLS, qv_bill_index);
    SLEE_HDB_REC qh_ap_data = mp_dbms->get_data(LAKDB_APARTMENTS, qh_bill_data.value(FLD_BILL_AINDEX));
    int h_type =  mp_dbms->get_house_type(qh_ap_data.value(FLD_APDB_HSINDEX));
    SLEE_HDB_REC qh_ls_data;
    QString qstr_tfio = "   ";
    QString qstr_taddr = "   ";
    QDate qd = qh_bill_data.value(FLD_BILL_TARGETDATE).toDate();
    QString qstr_month = ui->combo_month->itemText(qd.month()-1);
    QString qstr_year = qd.toString("yyyy");
    if(qh_bill_data.value(FLD_BILL_LINDEX).toULongLong() != 0ll)
    {
        qh_ls_data = mp_dbms->get_data(LAKDB_LEASES, qh_bill_data.value(FLD_BILL_LINDEX));
        SLEE_HDB_REC qh_ten = mp_dbms->get_data(LAKDB_TENANTS, qh_ls_data.value(FLD_LS_TINDEX));
        qstr_tfio = mp_dbms->get_tenant_fio(qh_ten,true);
        qstr_taddr = qh_ten.value(FLD_TEN_REGADR).toString();
    }

    switch(act)
    {
    case EACT_FIO:
        return QVariant(qstr_tfio);
    case EACT_ADDR:
        return QVariant(mp_dbms->get_apartment_addr(qh_ap_data));
    case EACT_M_Y:
        return QVariant(qstr_month + " " + qstr_year);
    case EACT_TAR:
        return qh_bill_data.value(FLD_BILL_TARIFF);
    case EACT_SPC:
        if( h_type==0 )
            return QVariant(qh_ap_data.value(FLD_APDB_TSPC).toDouble());
        return QVariant(mp_dbms->get_apartment_lspace(qh_bill_data.value(FLD_BILL_AINDEX),
                                                      qh_bill_data.value(FLD_BILL_SPSLST).toStringList()));
    case EACT_TOTAL:
        return QVariant(QString("%1").arg(qh_bill_data.value(FLD_BILL_AMMOUNT).toDouble(),0,'f',2,QChar(' ') ) );
    case EACT_BILLID:
        return QVariant(QString("%1").arg(qv_bill_index.toULongLong()));
    }
    return QVariant();
}

void FormGetReceipt::export_reciept(SleeExcel &excel, const QVariant &qv_bill_index)
{
    SleeExcelBook *p_book;
    SleeExcelSheet *p_sheet;


    QString qstr_export_file;
    qstr_export_file = RUSTR("Квитанция №%1 за %2").arg(qv_bill_index.toULongLong()) \
                                                                    .arg(mqd_target.toString("MM-yyyy"));
    ui->list_info->addItem(RUSTR("Экспорт: ")+qstr_export_file);
    ui->list_info->scrollToBottom();
    qstr_export_file += ".xls";
    qstr_export_file.replace(' ', '_');
    QString qstr_filepathname = mqstr_root_dir + "\\" + mqstr_subdir + "\\" +qstr_export_file;
    qDebug()<<"Export file to: "<<qstr_filepathname;
    QFile::copy(mqstr_t_filename,qstr_filepathname);
    p_book = excel.open_workbook(qstr_filepathname);
    p_sheet = p_book->get_sheet(1);

    int row, col, act_num;
    QVariant val;
    for(int i = 0; i< m_act_lst.size(); i++ )
    {
        row = m_act_lst.at(i).first.first;
        col = m_act_lst.at(i).first.second;
        act_num = m_act_lst.at(i).second;
        val = process_act(act_num, qv_bill_index);
        p_sheet->put(row, col, val);
    }

    p_book->save();
    if(ui->chb_print->isChecked())
        p_sheet->print_out();
    excel.close_workbook(&p_book);
}
#endif

void FormGetReceipt::form_reciept()
{

    SleeQHash_Constrain constr;
    SleeQHash_Constrain *p_constr;
    constr.append(QVariant(0ll), FLD_BILL_LINDEX);
    if(ui->chb_do_by_lease->isChecked())
    {
        if(!ui->chb_do_by_nlease->isChecked())
        {
            constr.set_process_string("$0% > $0#");
            p_constr = &constr;
        }
        else
        {
            p_constr = NULL;
        }
    }
    else
    {
        if(ui->chb_do_by_nlease->isChecked())
        {
            constr.set_process_string("$0% = $0#");
            p_constr = &constr;
        }
        else
        {
            lakhMsgE()<<RUSTR("Ошибка! Пустое условие для экспорта.");
            return;
        }
    }

    QVariantList qvl_bills_indices = mp_dbms->get_db(LAKDB_BILLS)->findDataEq(FLD_BILL_TARGETDATE, QVariant(mqd_target),
                                                                              NULL, p_constr);
    qDebug()<<"bills loaded"<<qvl_bills_indices.size();

    ui->gb_options->hide();
    ui->frame_in_action->show();
    ui->btn_form_receipt->setEnabled(false);
    mqstr_subdir = RUSTR("Квитанции-");
    mqstr_subdir += ui->combo_year->currentText();
    mqstr_subdir += "-";
    mqstr_subdir += ui->combo_month->currentText();
    mqstr_root_dir = mp_settings->get_export_dirpath();

    if(ui->chb_use_dialog->isChecked())
    {
        QFileDialog qdlg;
        qdlg.setDirectory(mqstr_root_dir);
        qdlg.setFileMode(QFileDialog::Directory);
        if(qdlg.exec())
        {
            mqstr_root_dir = qdlg.selectedFiles().at(0);
        }
    }

    QDir().mkdir(mqstr_root_dir + "/" + mqstr_subdir);
    if(!QDir().exists(mqstr_root_dir + "/" + mqstr_subdir))
    {
        lakhMsg()<<RUSTR("Каталог экспорта документов не найден. ") \
                              <<mqstr_root_dir + "\\" + mqstr_subdir;
        return;
    }


#ifdef Q_OS_WIN
    lakhMsg()<<RUSTR("Загрузка Excel...");
    SleeExcel excel;
    SleeExcelBook *p_book;
    SleeExcelSheet *p_sheet;
    mqstr_t_filename = mp_settings->get_doc_dirpath() + "/receipt.xls";
    p_book = excel.open_workbook(mqstr_t_filename);
    p_sheet = p_book->get_sheet(1);
    scan_template(p_sheet);
    excel.close_workbook(&p_book);

    if(ui->chb_show_excel->isChecked()) excel.set_visible(true);

    lakhMsg()<<RUSTR("Экспорт квитанций...");
    int cntr = 0;
    int count = qvl_bills_indices.size();
    ui->progress_bar->setMaximum(count);
    ui->progress_bar->setMinimum(0);
    ui->progress_bar->setValue(0);
    foreach(QVariant qv_bill_index, qvl_bills_indices)
    {
        export_reciept(excel,qv_bill_index);

        lakhMsgF()<<RUSTR("Выполнено: ")<<(++cntr)<<"\\"<<count;
        ui->progress_bar->setValue(cntr);
    }

    if(ui->chb_close_excel->isChecked())
        excel.quit_excel();
#endif

    ui->gb_options->show();
    ui->frame_in_action->hide();
    ui->btn_form_receipt->setEnabled(true);
}


void FormGetReceipt::show_excel(bool state)
{
    if(state)
    {
        ui->chb_close_excel->setEnabled(true);
        ui->chb_close_excel->setChecked(true);
    }
    if(!state)
    {
        ui->chb_close_excel->setChecked(true);
        ui->chb_close_excel->setEnabled(false);
    }
}


void FormGetReceipt::set_dbms(HousingDBMS *p_dbms)
{
    mp_dbms = p_dbms;
    mp_bills_model = dynamic_cast<ModelContainer*>(mp_dbms->get_models())->get_bills_model();
}

void FormGetReceipt::update_model()
{
    ui->tv_bills->setModel(NULL);
    mqd_target = QDate(ui->combo_year->currentIndex()+2000, ui->combo_month->currentIndex()+1, 15);
    mp_bills_model->load_data(mqd_target,ui->chb_do_by_lease->isChecked(), ui->chb_do_by_nlease->isChecked());
    ui->tv_bills->setModel(mp_bills_model);
    resize_table();
}

void FormGetReceipt::showEvent(QShowEvent *p_e)
{
    update_model();
    QWidget::showEvent(p_e);
}


void FormGetReceipt::generate_bills()
{

    SleeQHash_Constrain date_constr;
    date_constr.append(QVariant(mqd_target), FLD_BILL_TARGETDATE);
    date_constr.set_process_string("$0%=$0#");


    QVariantList qvl_ap_indices = mp_dbms->get_db(LAKDB_APARTMENTS)->findDataRange(-1);
    qvl_ap_indices.removeFirst();

    ui->frame_in_action->show();
    ui->progress_bar->setMinimum(0);
    ui->progress_bar->setMaximum(qvl_ap_indices.size());
    ui->progress_bar->setValue(0);
    ui->gb_target_date->setEnabled(false);
    int cntr=0;
    foreach(QVariant qv_ap_index, qvl_ap_indices)
    {
        SLEE_HDB_REC_LST qhl_ex_bill_data;
        mp_dbms->get_db(LAKDB_BILLS)->findDataEq(FLD_BILL_AINDEX, qv_ap_index,&qhl_ex_bill_data,&date_constr);
        QStringList qsl_ex_sids;
        QVariantList qvl_ex_ls_indices;

        for(int i=0; i < qhl_ex_bill_data.size(); i++)
        {
            qsl_ex_sids.append(qhl_ex_bill_data.at(i).value(FLD_BILL_SPSLST).toStringList());
            qvl_ex_ls_indices.append(qhl_ex_bill_data.at(i).value(FLD_BILL_LINDEX));
        }

        SLEE_HDB_REC qh_ap_data = mp_dbms->get_data(LAKDB_APARTMENTS, qv_ap_index);
        SLEE_HDB_REC qh_h_data = mp_dbms->get_data(LAKDB_HOUSES, qh_ap_data.value(FLD_APDB_HSINDEX));
        int h_type = qh_h_data.value(FLD_HSDB_TYPE).toInt();
        double tariff = qh_h_data.value(FLD_HSDB_TARIFF).toDouble();

        QVariantHash qvh_spaces = qh_ap_data.value(FLD_APDB_LSPSHASH).toHash();

        QVariantList qvl_ls_indices = mp_dbms->get_lease_for_ap(qv_ap_index, mqd_target);
        QStringList qsl_lses_sids;
        SLEE_HDB_REC qh_bill_data;

        foreach(QVariant qv_ls_index, qvl_ls_indices)
        {
            SLEE_HDB_REC qh_ls_data = mp_dbms->get_data(LAKDB_LEASES, qv_ls_index);
            QStringList qsl_lease_sids = qh_ls_data.value(FLD_LS_SPSLST).toStringList();
            double ls_space = mp_dbms->get_apartment_lspace(qv_ap_index, qsl_lease_sids);
            qh_bill_data[FLD_BILL_AINDEX] = qv_ap_index;
            qh_bill_data[FLD_BILL_LINDEX] = qv_ls_index;
            qh_bill_data[FLD_BILL_TARGETDATE] = mqd_target;
            qh_bill_data[FLD_BILL_SPSLST] = qsl_lease_sids;
            qh_bill_data[FLD_BILL_TARIFF] = QVariant(tariff);
            if(h_type == 0) qh_bill_data[FLD_BILL_AMMOUNT] = (double) (qh_ap_data.value(FLD_APDB_TSPC).toDouble() * tariff);
            else qh_bill_data[FLD_BILL_AMMOUNT] = ls_space * tariff;
            bool ls_exist = false;
            if(qvl_ex_ls_indices.contains(qv_ls_index)) ls_exist = true;
            if(!ls_exist)
                mp_dbms->db_put(LAKDB_BILLS,qh_bill_data);
            qsl_lses_sids.append(qsl_lease_sids);
        }
        QVariantHash qvh_pdate = qh_ap_data.value(FLD_APDB_PDATEHASH).toHash();

        foreach(QString qstr_id, qvh_spaces.keys())
        {
            if(qsl_lses_sids.contains(qstr_id)) continue;
            QDate qd_p = qvh_pdate.value(qstr_id).toDate();
            if((qd_p.isValid()) && (qd_p < mqd_target)) continue;
            qh_bill_data[FLD_BILL_AINDEX] = qv_ap_index;
            qh_bill_data[FLD_BILL_LINDEX] = QVariant((quint64) 0ll);
            qh_bill_data[FLD_BILL_TARGETDATE] = mqd_target;
            qh_bill_data[FLD_BILL_SPSLST] = QVariant(QStringList()<<qstr_id);
            qh_bill_data[FLD_BILL_TARIFF] = QVariant(tariff);
            double space;
            if(h_type == 0) space = qh_ap_data.value(FLD_APDB_TSPC).toDouble();
            else space = qvh_spaces.value(qstr_id).toDouble();
            qh_bill_data[FLD_BILL_AMMOUNT] = space * tariff;
            if(!qsl_ex_sids.contains(qstr_id))
                mp_dbms->db_put(LAKDB_BILLS,qh_bill_data);
        }
        ui->progress_bar->setValue(++cntr);
        qDebug()<<"Bills generating: "<<cntr<<qvl_ap_indices.size()-1;
    }
    ui->gb_target_date->setEnabled(true);
    ui->frame_in_action->hide();
    update_model();
    lakhMsg()<<RUSTR("Квитанции за указанный период сформированы.");
}

void FormGetReceipt::del_selected_bill()
{
      QModelIndex qmi = ui->tv_bills->currentIndex();
      if(!qmi.isValid())
      {
          lakhMsgE()<<RUSTR("Ошибка! Не выбрана квитанция.");
          return;
      }
      QVariant qv_bill_index = mp_bills_model->get_db_index(qmi);
      if(!mp_dbms->can_remove(LAKDB_BILLS, qv_bill_index)) return;
      SLEE_HDB_REC qh_bill = mp_dbms->get_data(LAKDB_BILLS, qv_bill_index);
      mp_dbms->get_db(LAKDB_BILLS)->removeData(qh_bill,qv_bill_index);
      lakhMsg()<<RUSTR("Квитанция из БД удалена.");
      update_model();
}


void FormGetReceipt::resize_table()
{
    int w = ui->tv_bills->size().width();
    //global id - 0
    //targed date 1
    //lease id - 2
    //ap_addr - 3
    //total space-4
    //ammount   5
    ui->tv_bills->setColumnWidth(0, w/8);
    ui->tv_bills->setColumnWidth(1, w/8);
    ui->tv_bills->setColumnWidth(2, w/8);
    ui->tv_bills->setColumnWidth(3, w*30/100);
    ui->tv_bills->setColumnWidth(4, w/8);
    ui->tv_bills->setColumnWidth(5, w/8);
}

void FormGetReceipt::resizeEvent(QResizeEvent *p_e)
{
    resize_table();
    QWidget::resizeEvent(p_e);
}

void FormGetReceipt::target_date_changed()
{
    mqd_target = QDate(ui->combo_year->currentIndex()+2000, ui->combo_month->currentIndex()+1, 15);
    ui->label_target_date->setText(RUSTR("Оплачиваемый период: ") + ui->combo_year->currentText() + " " \
                                                                              + ui->combo_month->currentText());
}
